package org.scaffold.jdbc;


import org.apache.commons.lang3.StringUtils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 表实体类
 */
public class TableInfo {
    /**
     * 名称
     */
    private String name;
    /**
     * 名称
     */
    private String packageName;
    /**
     * 备注
     */
    private String comment;
    /**
     * 主键
     */
    private Column primaryKey;


    private List<Column> columns = new ArrayList<>();

    /**
     * 字段
     */
    public static class Column {
        /**
         * 名称
         */
        private String name;
        /**
         * 备注
         */
        private String comment;
        private Class javaType;

        public Class getJavaType() {
            return javaType;
        }

        public void setJavaType(Class javaType) {
            this.javaType = javaType;
        }

        public String getJavaTypeName() {
            return this.javaType.getName();
        }

        public String getJavaTypeSimpleName() {
            return this.javaType.getSimpleName();
        }

        public String getJavaName() {
            return StringUtils.capitalize(underscoreToCamel(this.name));
        }

        public String getJavaSimpleName() {
            return underscoreToCamel(this.name);
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getComment() {
            return comment;
        }

        public void setComment(String comment) {
            this.comment = comment;
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public List<Column> getColumns() {
        return columns;
    }

    public void setColumns(List<Column> columns) {
        this.columns = columns;
    }

    public String getJavaName() {
        return StringUtils.capitalize(underscoreToCamel(this.name));
    }

    public String getJavaSimpleName() {
        return underscoreToCamel(this.name);
    }

    public Set<String> getImportPackage() {
        Set<String> set = new HashSet<>();
        for (Column column : columns) {
            if (!column.getJavaTypeName().contains("java.lang")){
                set.add(column.getJavaTypeName());
            }
        }
        return set;
    }

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    /**
     * 下划线转为驼峰
     */
    public static String underscoreToCamel(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        StringBuilder sb = new StringBuilder(param);
        Matcher mc = Pattern.compile("_").matcher(param);
        int i = 0;
        while (mc.find()) {
            int position = mc.end() - (i++);
            //String.valueOf(Character.toUpperCase(sb.charAt(position)));
            sb.replace(position - 1, position + 1, sb.substring(position, position + 1).toUpperCase());
        }
        return sb.toString();
    }

    // Map --> Bean 1: 利用Introspector,PropertyDescriptor实现 Map --> Bean
    public Map<String, Object> transMap(Object obj) {
        if (obj == null) {
            obj = this;
        }
        Map<String, Object> map = new HashMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if (!"class".equals(key)) {
                    Object value = property.getReadMethod().invoke(obj);
                    if (value instanceof List) {
                        List<Map<String, Object>> mapList = new ArrayList<>();
                        List valList = (List) value;
                        map.put("columnLength",valList.size());
                        for (Object o : valList) {
                            mapList.add(this.transMap(o));
                        }
                        value = mapList;
                    }
                    if ("primaryKey".equals(key)) {
                        value = this.transMap(value);
                    }
                    map.put(key, value);
                }
            }
        } catch (Exception e) {
            System.out.println("transMap Error " + e);
        }
        return map;
    }

    public Column getPrimaryKey() {
        return primaryKey;
    }

    public void setPrimaryKey(Column primaryKey) {
        this.primaryKey = primaryKey;
    }
}
